﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DevExpress.Utils;
using DevExpress.XtraEditors;
using FileManager_Client.BusinessLogic;
using FileManager_Client.BusinessLogic.FileManagerUserService;
using FileManager_Client.Utility;

namespace FileManager_Client.PresentationLayer
{
    public partial class AddEmployee : Form
    {
        private WaitDialogForm _waitBeforeLogin;
        private UserService _userService;
        private ToolTip _fileNameToolTip = new ToolTip();
        private List<CompanyResult> _companyResults;
        private List<CompanyGroupResult> _companyGroupResults;
        private List<UserGroupResult> _userGroupResults;
        public List<UserResult> ChooseUser { get; set; } 
        private static readonly object lockWait =new object();
        public AddEmployee()
        {
            InitializeComponent();
            _fileNameToolTip.AutoPopDelay = 5000;
            _fileNameToolTip.InitialDelay = 1000;
            _fileNameToolTip.ReshowDelay = 500;
            _fileNameToolTip.ShowAlways = true;
            _fileNameToolTip.IsBalloon = true;
            _fileNameToolTip.ToolTipIcon = ToolTipIcon.Error;
            _fileNameToolTip.Active = true;
            _fileNameToolTip.ToolTipTitle = "输入提示:";
            tb_SearchPeopleName.TextChanged += tb_SearchPeopleName_TextChanged;
            _userService = new UserService();
            lv_AddEmployee.Items.Clear();
            lv_SearchResult.Items.Clear();
            ChooseUser = new List<UserResult>();
            tb_SearchPeopleName.KeyPress += tb_SearchPeopleName_KeyPress;
        }

        void tb_SearchPeopleName_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar != 13) return;
            SearchUserByName();
        }

        void tb_SearchPeopleName_TextChanged(object sender, EventArgs e)
        {
            _fileNameToolTip.Hide(tb_SearchPeopleName);
        }

        private void btn_Confrim_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in lv_AddEmployee.Items)
            {
                ChooseUser.Add(item.Tag as UserResult);
            }
            Close();
        }

        private void tc_Collection_SelectedIndexChanged(object sender, EventArgs e)
        {
            _fileNameToolTip.Hide(tb_SearchPeopleName);
            lv_SearchResult.Items.Clear();
            tc_Collection.SelectedTab.Controls.Add(pl_MoveControl); 
        }

        private void btn_SearchPeople_Click(object sender, EventArgs e)
        {
            SearchUserByName();
        }

        private void SearchUserByName()
        {
            try
            {
                _fileNameToolTip.Hide(tb_SearchPeopleName);
                if (string.IsNullOrEmpty(tb_SearchPeopleName.Text.Trim()))
                {
                    _fileNameToolTip.Show(string.Empty, tb_SearchPeopleName, 0);
                    _fileNameToolTip.Show("关键字不能为空!", tb_SearchPeopleName, 0);
                    return;
                }
                lock (lockWait)
                {
                    _waitBeforeLogin = new WaitDialogForm(GlobalString.System_Config_String.SearchUserStr,
                                                          GlobalString.System_Config_String.MbxInfoStr)
                    {
                        BackColor = BackColor
                    };
                    _waitBeforeLogin.Hide();
                }
                var backgroundWorker = new BackgroundWorker();
                backgroundWorker.DoWork += backgroundWorker_DoWork;
                var searchKey = new SearchUserNameArgs
                {
                    NameKeyk__BackingField = tb_SearchPeopleName.Text
                };
                backgroundWorker.RunWorkerAsync(searchKey);
                _waitBeforeLogin.ShowDialog();
            }
            catch (Exception ex)
            {
                LogLoader.Instance.Log.Error("btn_SearchPeople_Click has problem", ex);
                XtraMessageBox.Show("搜索用户失败，请联系管理员!", GlobalString.System_Exception_String.MbxErrorStr, MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);
            }
        }

        void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            var result = _userService.SearchUserByName(e.Argument as SearchUserNameArgs);
            Invoke((EventHandler) delegate
                                      {
                                          _waitBeforeLogin.Close();
                                          lv_SearchResult.Items.Clear();
                                          foreach (var userResult in result.Resultk__BackingField)
                                          {
                                              var listViewItem = new ListViewItem
                                                                     {
                                                                         Text = userResult.UserNamek__BackingField,
                                                                         ImageKey = "people",
                                                                         Tag = userResult
                                                                     };
                                              var subListViewItem = new ListViewItem.ListViewSubItem
                                                                        {Text = userResult.CompanyNamek__BackingField};
                                              listViewItem.SubItems.Add(subListViewItem);
                                              lv_SearchResult.Items.Add(listViewItem);
                                          }
                                      });
        }

        private void btn_AddEmployee_Click(object sender, EventArgs e)
        {
            if (lv_SearchResult.Items.Count <= 0) return;
            foreach (var listViewItem 
                in from ListViewItem temp in lv_SearchResult.SelectedItems 
                   select temp.Tag as UserResult into user 
                   where lv_AddEmployee.Items.Find(user.UserIdk__BackingField, true).Length <= 0 
                   select new ListViewItem
                                                        {
                                                            Text = user.UserNamek__BackingField,
                                                            ImageKey = "people",
                                                            Tag = user,
                                                            Name = user.UserIdk__BackingField
                                                        })
            {
                lv_AddEmployee.Items.Add(listViewItem);
            }
        }

        private void btn_AddAllEmployee_Click(object sender, EventArgs e)
        {
            if (lv_SearchResult.Items.Count <= 0) return;
            foreach (var listViewItem
            in from ListViewItem temp in lv_SearchResult.Items
               select temp.Tag as UserResult into user
               where lv_AddEmployee.Items.Find(user.UserIdk__BackingField, true).Length <= 0
               select new ListViewItem
               {
                   Text = user.UserNamek__BackingField,
                   ImageKey = "people",
                   Tag = user,
                   Name = user.UserIdk__BackingField
               })
            {
                lv_AddEmployee.Items.Add(listViewItem);
            }
        }

        private void btn_DeleteEmployee_Click(object sender, EventArgs e)
        {
            if(lv_AddEmployee.SelectedItems.Count <= 0) return;
            foreach (ListViewItem temp in lv_AddEmployee.SelectedItems)
            {
                lv_AddEmployee.Items.Remove(temp);
            }
        }

        private void btn_DeleteAllEmployee_Click(object sender, EventArgs e)
        {
            lv_AddEmployee.Items.Clear();
        }

        private void SetCacheData()
        {
            try
            {
                lock (lockWait)
                {
                    _waitBeforeLogin = new WaitDialogForm(GlobalString.System_Config_String.GetCompanyGroupAndUserGroup,
                                                          GlobalString.System_Config_String.MbxInfoStr)
                    {
                        BackColor = BackColor
                    };
                    _waitBeforeLogin.Hide();
                }
                var backgroundWorkerGetCompanyInfo = new BackgroundWorker();
                backgroundWorkerGetCompanyInfo.DoWork += backgroundWorkerGetCompanyInfo_DoWork;
                backgroundWorkerGetCompanyInfo.RunWorkerAsync();
                _waitBeforeLogin.ShowDialog();
            }
            catch (Exception ex)
            {
                LogLoader.Instance.Log.Error("SetCacheData has problem", ex);
                XtraMessageBox.Show("获取组织机构失败，请联系管理员!", GlobalString.System_Exception_String.MbxErrorStr, MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);
            }
        }

        void backgroundWorkerGetCompanyInfo_DoWork(object sender, DoWorkEventArgs e)
        {
            var result = _userService.GetCompanyGroupAndUserGroup();
            CacheGlobal.Add(GlobalString.System_Config_String.AllCompanyCollectionCache, result.CompanyResultsk__BackingField.ToList());
            CacheGlobal.Add(GlobalString.System_Config_String.CompanyGroupCollectionCache,result.CompanyGroupResultsk__BackingField.ToList());
            CacheGlobal.Add(GlobalString.System_Config_String.UserGroupCollectionCache,result.UserGroupResultsk__BackingField.ToList());
            if(!IsHandleCreated)
                CreateHandle();
            Invoke((EventHandler) delegate
                                      {
                                          _waitBeforeLogin.Close();
                                      });
        }

        private void AddEmployee_Shown(object sender, EventArgs e)
        {
            _companyResults =
    CacheGlobal.GetCache(GlobalString.System_Config_String.AllCompanyCollectionCache) as List<CompanyResult>;
            _companyGroupResults =
                CacheGlobal.GetCache(GlobalString.System_Config_String.CompanyGroupCollectionCache) as List<CompanyGroupResult>;
            _userGroupResults =
                CacheGlobal.GetCache(GlobalString.System_Config_String.UserGroupCollectionCache) as List<UserGroupResult>;
            if (null == _companyResults || null == _companyGroupResults || null == _userGroupResults)
                SetCacheData();
            _companyResults =
CacheGlobal.GetCache(GlobalString.System_Config_String.AllCompanyCollectionCache) as List<CompanyResult>;
            _companyGroupResults =
                CacheGlobal.GetCache(GlobalString.System_Config_String.CompanyGroupCollectionCache) as List<CompanyGroupResult>;
            _userGroupResults =
                CacheGlobal.GetCache(GlobalString.System_Config_String.UserGroupCollectionCache) as List<UserGroupResult>;
            #region 组织结构公共组

            var companyGroupRoot = _companyGroupResults.Where(x => x.Pidk__BackingField==0).ToList();
            foreach (var companyGroupResult in companyGroupRoot)
            {
                var rootNode = new TreeNode
                                   {
                                       Text = companyGroupResult.Namek__BackingField,
                                       Tag = companyGroupResult
                                   };
                var subItemCollection = FindCompanyGroupSubItem(companyGroupResult.GroupIdk__BackingField);
                foreach (var treeNode in subItemCollection)
                    rootNode.Nodes.Add(treeNode);
                tv_CompanGroup.Nodes.Add(rootNode);
            }
            var userGroupRoot = _userGroupResults.Where(x => x.Pidk__BackingField == 0);
            foreach (var userGroupResult in userGroupRoot)
            {
                var rootNode = new TreeNode
                {
                    Text = userGroupResult.Namek__BackingField,
                    Tag = userGroupResult
                };
                var subItemCollection = FindUserGroupSubItem(userGroupResult.Idk__BackingField);
                foreach (var treeNode in subItemCollection)
                    rootNode.Nodes.Add(treeNode);
                tv_EmployeeGroup.Nodes.Add(rootNode);
            }
            var companyRoot = _companyResults.Where(x => string.IsNullOrEmpty(x.Pidk__BackingField));
            foreach (var companyResult in companyRoot)
            {
                var rootNode = new TreeNode
                {
                    Text = companyResult.ShortNamek__BackingField,
                    Tag = companyResult
                };
                var subItemCollection = FindGroupSubItem(companyResult.Idk__BackingField);
                foreach (var treeNode in subItemCollection)
                    rootNode.Nodes.Add(treeNode);
                tv_Company.Nodes.Add(rootNode);
            }

            #endregion
        }

        #region while company group and user group data
        private IEnumerable<TreeNode> FindCompanyGroupSubItem(int groupId)
        {
            var result = new List<TreeNode>();
            var subCompanyGroup = _companyGroupResults.Where(x => x.Pidk__BackingField==groupId);
            foreach (var companyGroupResult in subCompanyGroup)
            {
                var subItem = new TreeNode
                                  {
                                      Text = companyGroupResult.Namek__BackingField,
                                      Tag = companyGroupResult
                                  };
                var subSubItemCollection = FindCompanyGroupSubItem(companyGroupResult.GroupIdk__BackingField);
                foreach (var treeNode in subSubItemCollection)
                    subItem.Nodes.Add(treeNode);
                result.Add(subItem);
            }
            return result;
        }

        private IEnumerable<TreeNode> FindUserGroupSubItem(int groupId)
        {
            var result = new List<TreeNode>();
            var subUserGroup = _userGroupResults.Where(x => x.Pidk__BackingField==groupId);
            foreach (var userGroupResult in subUserGroup)
            {
                var subItem = new TreeNode
                {
                    Text = userGroupResult.Namek__BackingField,
                    Tag = userGroupResult
                };
                var subSubItemCollection = FindUserGroupSubItem(userGroupResult.Idk__BackingField);
                foreach (var treeNode in subSubItemCollection)
                    subItem.Nodes.Add(treeNode);
                result.Add(subItem);
            }
            return result;
        }

        private  IEnumerable<TreeNode> FindGroupSubItem(string sid)
        {
            var result = new List<TreeNode>();
            var subCompany = _companyResults.Where(x => x.Pidk__BackingField.Equals(sid));
            foreach (var companyResult in subCompany)
            {
                var subItem = new TreeNode
                {
                    Text = companyResult.ShortNamek__BackingField,
                    Tag = companyResult
                };
                var subSubItemCollection = FindGroupSubItem(companyResult.Idk__BackingField);
                foreach (var treeNode in subSubItemCollection)
                    subItem.Nodes.Add(treeNode);
                result.Add(subItem);
            }
            return result;
        }
        #endregion

        private void tv_CompanGroup_AfterSelect(object sender, TreeViewEventArgs e)
        {
              var args = new SearchUserByCompanyCodeArgs
                               {
                                   SearchUserByCompanyEnumk__BackingField = SearchUserByCompanyEnum.CompanyGroup
                               };
            if(e.Node.Nodes.Count > 0)
            {
                var objectCollection = (from TreeNode temp in e.Node.Nodes from o in ReturnTreeNodeList(temp) select o).ToList();
                args.CodeCollectionk__BackingField = objectCollection.OfType<CompanyGroupResult>().Select(obj => obj.GroupIdk__BackingField.ToString()).ToArray();
            }
            else
            {
                var obj = e.Node.Tag as CompanyGroupResult;
                args.CodeCollectionk__BackingField = (new List<string> { obj.GroupIdk__BackingField.ToString() }).ToArray();
            }
            SearchUserByCompanCode(args);
        }

        private IEnumerable<object> ReturnTreeNodeList(TreeNode treeNode)
        {
            var objectCollection = new List<object>();
            if(treeNode.Nodes.Count > 0)
            {
                foreach (TreeNode o in treeNode.Nodes)
                {
                    var tempNodes =  ReturnTreeNodeList(o);
                    foreach (object tempNode in tempNodes)
                    {
                        objectCollection.Add(tempNode);
                    }
                }
                //objectCollection.AddRange(from TreeNode node in treeNode.Nodes from TreeNode o in ReturnTreeNodeList(node) select o.Tag);
            }
            else
                objectCollection.Add(treeNode.Tag);
            return objectCollection;
        }

        private void tv_EmployeeGroup_AfterSelect(object sender, TreeViewEventArgs e)
        {
            var args = new SearchUserByCompanyCodeArgs
            {
                SearchUserByCompanyEnumk__BackingField = SearchUserByCompanyEnum.UserGroup
            };
            if (e.Node.Nodes.Count > 0)
            {
                var objectCollection = (from TreeNode temp in e.Node.Nodes from o in ReturnTreeNodeList(temp) select o).ToList();
                args.CodeCollectionk__BackingField = objectCollection.OfType<UserGroupResult>().Select(obj => obj.Idk__BackingField.ToString()).ToArray();
            }
            else
            {
                var obj = e.Node.Tag as UserGroupResult;
                args.CodeCollectionk__BackingField = (new List<string> { obj.Idk__BackingField.ToString() }).ToArray();
            }
            SearchUserByCompanCode(args);
        }

        private void tv_Company_AfterSelect(object sender, TreeViewEventArgs e)
        {
            var args = new SearchUserByCompanyCodeArgs
            {
                SearchUserByCompanyEnumk__BackingField = SearchUserByCompanyEnum.Company
            };
            if (e.Node.Nodes.Count > 0)
            {
                var objectCollection = (from TreeNode temp in e.Node.Nodes from o in ReturnTreeNodeList(temp) select o).ToList();
                args.CodeCollectionk__BackingField = objectCollection.OfType<CompanyResult>().Select(obj => obj.Idk__BackingField).ToArray();
            }
            else
            {
                var obj = e.Node.Tag as CompanyResult;
                args.CodeCollectionk__BackingField = (new List<string> { obj.Idk__BackingField }).ToArray();
            }
            SearchUserByCompanCode(args);
        }

        private void SearchUserByCompanCode(SearchUserByCompanyCodeArgs searchUserByCompanyCodeArgs)
        {
            try
            {
                lock (lockWait)
                {
                    _waitBeforeLogin = new WaitDialogForm(GlobalString.System_Config_String.SearchUserStr,
                                                          GlobalString.System_Config_String.MbxInfoStr)
                    {
                        BackColor = BackColor
                    };
                    _waitBeforeLogin.Hide();
                }
                var backgroundWorkerSearchUserCompanyCode = new BackgroundWorker();
                backgroundWorkerSearchUserCompanyCode.DoWork += backgroundWorkerSearchUserCompanyCode_DoWork;
                backgroundWorkerSearchUserCompanyCode.RunWorkerAsync(searchUserByCompanyCodeArgs);
                _waitBeforeLogin.ShowDialog();
            }
            catch (Exception ex)
            {
                LogLoader.Instance.Log.Error("SearchUserByCompanCode has problem", ex);
                XtraMessageBox.Show("获取用户失败，请联系管理员!", GlobalString.System_Exception_String.MbxErrorStr, MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);
            }
        }

        void backgroundWorkerSearchUserCompanyCode_DoWork(object sender, DoWorkEventArgs e)
        {
            var result = _userService.SearchUserByCompanyCode(e.Argument as SearchUserByCompanyCodeArgs);
            Invoke((EventHandler)delegate
            {
                _waitBeforeLogin.Close();
                lv_SearchResult.Items.Clear();
                foreach (var userResult in result.Resultk__BackingField)
                {
                    var listViewItem = new ListViewItem
                    {
                        Text = userResult.UserNamek__BackingField,
                        ImageKey = "people",
                        Tag = userResult
                    };
                    var subListViewItem = new ListViewItem.ListViewSubItem { Text = userResult.CompanyNamek__BackingField };
                    listViewItem.SubItems.Add(subListViewItem);
                    lv_SearchResult.Items.Add(listViewItem);
                }
            });
        }
    }
}
